/*
 * CDatabase.java
 *
 * Copyright (c) 2009 Giles Millward (Manigra). All rights reserved.
 *
 * This file is part of JRogueDPS.
 *
 * JRogueDPS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * JRogueDPS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with JRogueDPS.  If not, see <http://www.gnu.org/licenses/>.
 */

package geardatabase;

import geardatabase.CGemType.GemType;
import geardatabase.CItemSlot.ItemSlot;
import geardatabase.CItemType.ItemType;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JTable;
import jroguedps.CGlobal;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import utility.CMessage;
import utility.CStatus;

/**
 *
 * @author Mani
 */
public class CDatabase {

    private JTable m_armorTable;
    private JTable m_weaponTable;
    private JTable m_gemTable;

    private HashMap<Integer, CItem> m_itemMap = new HashMap<Integer, CItem>();
    CItem m_nullItem = new CItem(0, "None", ItemSlot.UNKNOWN, ItemType.UNKNOWN, new CStats());

    public void linkTables(JTable p_armorTable, JTable p_weaponTable, JTable p_gemTable)
    {
        m_armorTable = p_armorTable;
        m_weaponTable = p_weaponTable;
        m_gemTable = p_gemTable;
    }

    public void refreshTables()
    {
        ((CDBTableModel) m_armorTable.getModel()).refreshTable();
        ((CDBTableModel) m_weaponTable.getModel()).refreshTable();
        ((CDBTableModel) m_gemTable.getModel()).refreshTable();
    }

    public CItem getItem(String p_itemId)
    {
        return this.getItem(Integer.parseInt(p_itemId), false);
    }

    public CItem getItem(String p_itemId, boolean p_pullFromWowHead)
    {
        return this.getItem(Integer.parseInt(p_itemId), p_pullFromWowHead);
    }

    public CItem getItem(int p_itemId)
    {
        return getItem(p_itemId, false);
    }

    public CItem getItem(int p_itemId, boolean p_pullFromWowHead)
    {
        CItem l_item = m_itemMap.get(p_itemId);
        if (l_item == null)
        {
            if (p_pullFromWowHead)
            {
                // Not found, try and import it
                if (!this.addDbItem(p_itemId, true))
                {
                    CMessage.showError("Unable to pull item " + p_itemId + " from wowhead.com!");
                    return null;
                }

                this.saveDatabase();
                this.refreshTables();
                return m_itemMap.get(p_itemId);
            }
            else
            {
                // Get Item labelled 'None'
                return m_itemMap.get(0);
            }
        }

        return m_itemMap.get(p_itemId);
    }

    public boolean addDbItem(CItem p_DbItem, boolean p_overWrite)
    {
        // check if entry already exists
        if (m_itemMap.containsKey(p_DbItem.getId()))
        {
            if (!p_overWrite) {
                // Duplicate already in there
                return false;
            }
            else
            {
                m_itemMap.remove(p_DbItem.getId());
            }
        }

        m_itemMap.put(p_DbItem.getId(), p_DbItem);
        return true;
    }

    public boolean addDbItem(String p_item, boolean p_overWrite)
    {
        return addDbItem(Integer.parseInt(p_item), p_overWrite);
    }

    public boolean addDbItem(int p_item, boolean p_overWrite)
    {
        // check if entry already exists
        if (m_itemMap.containsKey(p_item))
        {
            if (!p_overWrite) {
                // Duplicate already in there
                return false;
            }
            else
            {
                m_itemMap.remove(p_item);
            }
        }

        CWowHeadItemImporter l_importer = new CWowHeadItemImporter();
        CStatus.setStatus("Importing item " + p_item + " from wowhead");
        CItem l_dbItem = l_importer.getWowHeadItem(p_item);
        if (l_dbItem == null)
        {
            CStatus.idleStatus();
            return false;
        }

        CStatus.idleStatus();
        m_itemMap.put(p_item, l_dbItem);
        return true;
    }

    public boolean addDbItemFromLink(String p_url)
    {
        CWowHeadItemImporter l_importer = new CWowHeadItemImporter();
        CStatus.setStatus("Importing " + p_url + " from wowhead");
        CItem l_dbItem = l_importer.getWowHeadItem(p_url);
        if (l_dbItem == null)
        {
            CStatus.idleStatus();
            return false;
        }

        CStatus.idleStatus();
        // check if entry already exists
        if (m_itemMap.containsKey(l_dbItem.getId()))
        {
            m_itemMap.remove(l_dbItem.getId());
        }

        m_itemMap.put(l_dbItem.getId(), l_dbItem);
        return true;
    }

    public ArrayList<CItem> getListBySlot(ItemSlot p_itemSlot)
    {
        return getListBySlot(p_itemSlot, new CQualityFilter(true, true, true, true, true));
    }

    public ArrayList<CItem> getListBySlot(ItemSlot p_itemSlot, CQualityFilter p_qualityFilter)
    {
        ArrayList<CItem> l_typeList = new ArrayList<CItem>();
        Iterator iterator = m_itemMap.keySet().iterator();
        while (iterator.hasNext()) {
            int l_key = (Integer) iterator.next();
            CItem l_item = m_itemMap.get(l_key);
            if (l_item.getItemSlot() == p_itemSlot &&
                    l_item.getItemType() != ItemType.POISON &&
                    l_item.getItemType() != ItemType.ENCHANT)
            {
                if (p_qualityFilter.isFiltered(l_item.getGearQuality()))
                {
                    l_typeList.add(l_item);
                }
            }
        }

        Collections.sort(l_typeList, new CItemComparatorQualityAlpha());
        return l_typeList;
    }

    public ArrayList<CItem> getListByType(ItemType p_itemType)
    {
        return getListByType(p_itemType, new CQualityFilter(true, true, true, true, true));
    }

    public ArrayList<CItem> getListByType(ItemType p_itemType, CQualityFilter p_qualityFilter)
    {
        ArrayList<CItem> l_typeList = new ArrayList<CItem>();
        Iterator iterator = m_itemMap.keySet().iterator();
        while (iterator.hasNext()) {
            int l_key = (Integer) iterator.next();
            CItem l_item = m_itemMap.get(l_key);
            if (l_item.getItemType() == p_itemType)
            {
                if (p_qualityFilter.isFiltered(l_item.getGearQuality()))
                {
                    l_typeList.add(l_item);
                }
            }
        }

        Collections.sort(l_typeList, new CItemComparatorQualityAlpha());
        return l_typeList;
    }

    public ArrayList<CItem> getListByTypeAndSlot(ItemType p_itemType, ItemSlot p_itemSlot)
    {
        return getListByTypeAndSlot(p_itemType, p_itemSlot, new CQualityFilter(true, true, true, true, true));
    }

    public ArrayList<CItem> getListByTypeAndSlot(ItemType p_itemType, ItemSlot p_itemSlot, CQualityFilter p_qualityFilter)
    {
        ArrayList<CItem> l_typeList = new ArrayList<CItem>();
        Iterator iterator = m_itemMap.keySet().iterator();
        while (iterator.hasNext()) {
            int l_key = (Integer) iterator.next();
            CItem l_item = m_itemMap.get(l_key);
            if (l_item.getItemType() == p_itemType &&
                    l_item.getItemSlot() == p_itemSlot)
            {
                if (p_qualityFilter.isFiltered(l_item.getGearQuality()))
                {
                    l_typeList.add(l_item);
                }
            }
        }

        Collections.sort(l_typeList, new CItemComparatorQualityAlpha());
        return l_typeList;
    }

    public ArrayList<CItem> getListForGems(GemType p_gemType)
    {
        return getListForGems(p_gemType, new CQualityFilter(true, true, true, true, true));
    }

    public ArrayList<CItem> getListForGems(GemType p_gemType, CQualityFilter p_qualityFilter)
    {
        ArrayList<CItem> l_typeList = new ArrayList<CItem>();
        Iterator iterator = m_itemMap.keySet().iterator();
        while (iterator.hasNext()) {
            int l_key = (Integer) iterator.next();
            CItem l_item = m_itemMap.get(l_key);
            if (l_item.getItemType() == ItemType.GEM &&
                    l_item.getGemType() == p_gemType)
            {
                if (p_qualityFilter.isFiltered(l_item.getGearQuality()))
                {
                    l_typeList.add(l_item);
                }
            }
        }

        Collections.sort(l_typeList, new CItemComparatorQualityAlpha());
        return l_typeList;
    }

    public ArrayList<CItem> getPoisonList()
    {
        ArrayList<CItem> l_typeList = new ArrayList<CItem>();
        Iterator iterator = m_itemMap.keySet().iterator();
        while (iterator.hasNext()) {
            int l_key = (Integer) iterator.next();
            CItem l_item = m_itemMap.get(l_key);
            if (l_item.getItemType() == ItemType.POISON)
            {
                l_typeList.add(l_item);
            }
        }

        Collections.sort(l_typeList, new CItemComparatorAlpha());
        return l_typeList;
    }

    public ArrayList<CItem> getEnchantListBySlot(ItemSlot p_itemSlot)
    {
        ArrayList<CItem> l_typeList = new ArrayList<CItem>();
        Iterator iterator = m_itemMap.keySet().iterator();
        while (iterator.hasNext()) {
            int l_key = (Integer) iterator.next();
            CItem l_item = m_itemMap.get(l_key);
            if (l_item.getItemType() == ItemType.ENCHANT)
            {
                if (p_itemSlot == ItemSlot.HEAD && l_item.getItemSlot() == p_itemSlot)
                {
                    l_typeList.add(l_item);
                } else if (p_itemSlot == ItemSlot.SHOULDERS && l_item.getItemSlot() == p_itemSlot)
                {
                    l_typeList.add(l_item);
                } else if (p_itemSlot == ItemSlot.BACK && l_item.getItemSlot() == p_itemSlot)
                {
                    l_typeList.add(l_item);
                } else if (p_itemSlot == ItemSlot.CHEST && l_item.getItemSlot() == p_itemSlot)
                {
                    l_typeList.add(l_item);
                } else if (p_itemSlot == ItemSlot.WRIST && l_item.getItemSlot() == p_itemSlot)
                {
                    l_typeList.add(l_item);
                } else if (p_itemSlot == ItemSlot.HANDS && l_item.getItemSlot() == p_itemSlot)
                {
                    l_typeList.add(l_item);
                } else if (p_itemSlot == ItemSlot.WAIST && l_item.getItemSlot() == p_itemSlot)
                {
                    l_typeList.add(l_item);
                } else if (p_itemSlot == ItemSlot.LEGS && l_item.getItemSlot() == p_itemSlot)
                {
                    l_typeList.add(l_item);
                } else if (p_itemSlot == ItemSlot.FEET && l_item.getItemSlot() == p_itemSlot)
                {
                    l_typeList.add(l_item);
                } else if ((p_itemSlot == ItemSlot.FINGER1 || p_itemSlot == ItemSlot.FINGER2) && 
                        l_item.getItemSlot() == ItemSlot.FINGER)
                {
                    l_typeList.add(l_item);
                } else if ((p_itemSlot == ItemSlot.MAINHAND || p_itemSlot == ItemSlot.OFFHAND) && 
                        l_item.getItemSlot() == ItemSlot.MAINHAND)
                {
                    l_typeList.add(l_item);
                } 
            }
        }

        Collections.sort(l_typeList, new CItemComparatorAlpha());
        return l_typeList;
    }

    public void saveDatabase() {
        Document doc = DocumentFactory.getInstance().createDocument();
        Element root = doc.addElement("root");

        Iterator iterator = m_itemMap.keySet().iterator();
        while (iterator.hasNext()) {
            int l_key = (Integer) iterator.next();
            CItem l_item = m_itemMap.get(l_key);
            if (!(l_item.getItemType() == ItemType.POISON || 
                    l_item.getItemType() == ItemType.ENCHANT ||
                    l_item.getId() == 0))
            {
                l_item.addXMLData(root);
            }
        }

        FileOutputStream fos;
        try {
            fos = new FileOutputStream("data/database/database.xml");
            OutputFormat format = OutputFormat.createPrettyPrint();
            XMLWriter writer;
            try {
                writer = new XMLWriter(fos, format);
                try {
                    writer.write(doc);
                    writer.flush();
                } catch (IOException ex) {
                    Logger.getLogger(CDatabase.class.getName()).log(Level.SEVERE, null, ex);
                }

            } catch (UnsupportedEncodingException ex) {
                Logger.getLogger(CDatabase.class.getName()).log(Level.SEVERE, null, ex);
            }

        } catch (FileNotFoundException ex) {
            Logger.getLogger(CDatabase.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void readDatabase()
    {
        File l_xml = new File("data/database/database.xml");
        SAXReader l_reader = new SAXReader();
        Document l_doc;
        try {
            l_doc = l_reader.read(l_xml);
            List l_list = l_doc.selectNodes( "//root/item" );

            for (Iterator l_iter = l_list.iterator(); l_iter.hasNext(); ) {
                Element l_element = (Element) l_iter.next();
                boolean l_result = addDbItem(new CItem(l_element), true);
         }
        } catch (DocumentException ex) {
            Logger.getLogger(CDatabase.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void listItems()
    {
        Iterator iterator = m_itemMap.keySet().iterator();
        while (iterator.hasNext()) {
            int l_key = (Integer) iterator.next();
            CItem l_item = m_itemMap.get(l_key);
        }

        iterator = m_itemMap.keySet().iterator();
        while (iterator.hasNext()) {
            int l_key = (Integer) iterator.next();
            CItem l_item = m_itemMap.get(l_key);
            System.out.print("," + l_key + " ");
        }

    }

    public void addEnchants()
    {
        boolean l_result;

        l_result = this.addDbItem(new CItem(368, "Greater Agility", ItemSlot.BACK, ItemType.ENCHANT, new CStats("Agility = 12")), true);
        l_result = this.addDbItem(new CItem(983, "Superior Agility", ItemSlot.BACK, ItemType.ENCHANT, new CStats("Agility = 16")), true);
        l_result = this.addDbItem(new CItem(1099, "Major Agility", ItemSlot.BACK, ItemType.ENCHANT, new CStats("Agility = 22")), true);
        l_result = this.addDbItem(new CItem(3256, "Shadow Armor", ItemSlot.BACK, ItemType.ENCHANT, new CStats("Agility = 10")), true);
        l_result = this.addDbItem(new CItem(3825, "Speed", ItemSlot.BACK, ItemType.ENCHANT, new CStats("HasteRating = 15")), true);
        l_result = this.addDbItem(new CItem(3831, "Greater Speed", ItemSlot.BACK, ItemType.ENCHANT, new CStats("HasteRating = 23")), true);

        l_result = this.addDbItem(new CItem(2661, "Exceptional Stats", ItemSlot.CHEST, ItemType.ENCHANT, new CStats("Agility = 6, Strength = 6, Stamina = 6, Intellect = 6, Spirit = 6")), true);
        l_result = this.addDbItem(new CItem(3252, "Super Stats", ItemSlot.CHEST, ItemType.ENCHANT, new CStats("Agility = 8, Strength = 8, Stamina = 8, Intellect = 8, Spirit = 8")), true);
        l_result = this.addDbItem(new CItem(3832, "Powerful Stats", ItemSlot.CHEST, ItemType.ENCHANT, new CStats("Agility = 10, Strength = 10, Stamina = 10, Intellect = 10, Spirit = 10")), true);
        l_result = this.addDbItem(new CItem(2933, "Major Resilience", ItemSlot.CHEST, ItemType.ENCHANT, new CStats("Resilience = 15")), true);
        l_result = this.addDbItem(new CItem(3245, "Exceptional Resilience", ItemSlot.CHEST, ItemType.ENCHANT, new CStats("Resilience = 20")), true);

        l_result = this.addDbItem(new CItem(1891, "Stats", ItemSlot.WRIST, ItemType.ENCHANT, new CStats("Agility = 4, Strength = 4, Stamina = 4, Intellect = 4, Spirit = 4")), true);
        l_result = this.addDbItem(new CItem(2661, "Greater Stats", ItemSlot.WRIST, ItemType.ENCHANT, new CStats("Agility = 6, Strength = 6, Stamina = 6, Intellect = 6, Spirit = 6")), true);
        l_result = this.addDbItem(new CItem(2564, "Superior Agility", ItemSlot.HANDS, ItemType.ENCHANT, new CStats("Agility = 15")), true);
        l_result = this.addDbItem(new CItem(3222, "Major Agility", ItemSlot.HANDS, ItemType.ENCHANT, new CStats("Agility = 20")), true);
        l_result = this.addDbItem(new CItem(3011, "Clefthide Leg Armor", ItemSlot.LEGS, ItemType.ENCHANT, new CStats("Agility = 10, Stamina = 30")), true);
        l_result = this.addDbItem(new CItem(3013, "Nethercleft Leg Armor", ItemSlot.LEGS, ItemType.ENCHANT, new CStats("Agility = 12, Stamina = 40")), true);
        l_result = this.addDbItem(new CItem(3325, "Jormungar Leg Armor", ItemSlot.LEGS, ItemType.ENCHANT, new CStats("Agility = 15, Stamina = 45")), true);
        l_result = this.addDbItem(new CItem(3822, "Frosthide Leg Armor", ItemSlot.LEGS, ItemType.ENCHANT, new CStats("Agility = 22, Stamina = 55")), true);
        l_result = this.addDbItem(new CItem(2939, "Cat's Swiftness", ItemSlot.FEET, ItemType.ENCHANT, new CStats("Agility = 6, MovementSpeed = 8")), true);
        l_result = this.addDbItem(new CItem(2940, "Boar's Speed", ItemSlot.FEET, ItemType.ENCHANT, new CStats("Stamina = 9, MovementSpeed = 8")), true);
        l_result = this.addDbItem(new CItem(3232, "Tuskarr's Vitality", ItemSlot.FEET, ItemType.ENCHANT, new CStats("Stamina = 15, MovementSpeed = 8")), true);
        l_result = this.addDbItem(new CItem(2657, "Dexterity", ItemSlot.FEET, ItemType.ENCHANT, new CStats("Agility = 12")), true);
        l_result = this.addDbItem(new CItem(983, "Superior Agility", ItemSlot.FEET, ItemType.ENCHANT, new CStats("Agility = 16")), true);
        l_result = this.addDbItem(new CItem(3824, "Assault", ItemSlot.FEET, ItemType.ENCHANT, new CStats("AttackPower = 24")), true);
        l_result = this.addDbItem(new CItem(1597, "Greater Assault", ItemSlot.FEET, ItemType.ENCHANT, new CStats("AttackPower = 32")), true);

        l_result = this.addDbItem(new CItem(2931, "Stats", ItemSlot.FINGER, ItemType.ENCHANT, new CStats("Agility = 4, Strength = 4, Stamina = 4, Intellect = 4, Spirit = 4")), true);
        l_result = this.addDbItem(new CItem(3791, "Stamina", ItemSlot.FINGER, ItemType.ENCHANT, new CStats("Stamina = 24")), true);


        l_result = this.addDbItem(new CItem(2543, "Arcanum of Rapidity", ItemSlot.HEAD, ItemType.ENCHANT, new CStats("HasteRating = 10")), true);
        l_result = this.addDbItem(new CItem(3003, "Arcanum of Ferocity", ItemSlot.HEAD, ItemType.ENCHANT, new CStats("AttackPower = 34, HitRating = 16")), true);
        l_result = this.addDbItem(new CItem(3817, "Arcanum of Torment", ItemSlot.HEAD, ItemType.ENCHANT, new CStats("AttackPower = 50, CritRating = 20")), true);
        l_result = this.addDbItem(new CItem(3096, "Arcanum of the Outcast", ItemSlot.HEAD, ItemType.ENCHANT, new CStats("Strength = 17, Intellect = 16")), true);
        l_result = this.addDbItem(new CItem(2717, "Might of the Scourge", ItemSlot.SHOULDERS, ItemType.ENCHANT, new CStats("AttackPower = 26, CritRating = 14")), true);
        l_result = this.addDbItem(new CItem(2997, "Greater Inscription of the Blade", ItemSlot.SHOULDERS, ItemType.ENCHANT, new CStats("AttackPower = 20, CritRating = 15")), true);
        l_result = this.addDbItem(new CItem(2986, "Greater Inscription of Vengeance", ItemSlot.SHOULDERS, ItemType.ENCHANT, new CStats("AttackPower = 30, CritRating = 10")), true);
        l_result = this.addDbItem(new CItem(2996, "Inscription of the Blade", ItemSlot.SHOULDERS, ItemType.ENCHANT, new CStats("CritRating = 13")), true);
        l_result = this.addDbItem(new CItem(2983, "Inscription of Vengeance", ItemSlot.SHOULDERS, ItemType.ENCHANT, new CStats("AttackPower = 26")), true);
        l_result = this.addDbItem(new CItem(2606, "Zandalar Signet of Might", ItemSlot.SHOULDERS, ItemType.ENCHANT, new CStats("AttackPower = 30")), true);

        l_result = this.addDbItem(new CItem(931, "Minor Haste", ItemSlot.HANDS, ItemType.ENCHANT, new CStats("HasteRating = 10")), true);
        l_result = this.addDbItem(new CItem(3012, "Nethercobra Leg Armor", ItemSlot.LEGS, ItemType.ENCHANT, new CStats("AttackPower = 50, CritRating = 12")), true);
        l_result = this.addDbItem(new CItem(3010, "Cobrahide Leg Armor", ItemSlot.LEGS, ItemType.ENCHANT, new CStats("AttackPower = 40, CritRating = 10")), true);
        l_result = this.addDbItem(new CItem(3823, "Icescale Leg Armor", ItemSlot.LEGS, ItemType.ENCHANT, new CStats("AttackPower = 75, CritRating = 22")), true);
        l_result = this.addDbItem(new CItem(3326, "Nerubian Leg Armor", ItemSlot.LEGS, ItemType.ENCHANT, new CStats("AttackPower = 55, CritRating = 15")), true);
        l_result = this.addDbItem(new CItem(2658, "Surefooted", ItemSlot.FEET, ItemType.ENCHANT, new CStats("CritRating = 10, HitRating = 10")), true);
        l_result = this.addDbItem(new CItem(3826, "Icewalker", ItemSlot.FEET, ItemType.ENCHANT, new CStats("CritRating = 12, HitRating = 12")), true);

        l_result = this.addDbItem(new CItem(3839, "Assault", ItemSlot.FINGER, ItemType.ENCHANT, new CStats("AttackPower = 32")), true);
        l_result = this.addDbItem(new CItem(1593, "Assault", ItemSlot.WRIST, ItemType.ENCHANT, new CStats("AttackPower = 24")), true);
        l_result = this.addDbItem(new CItem(1600, "Striking", ItemSlot.WRIST, ItemType.ENCHANT, new CStats("AttackPower = 38")), true);
        l_result = this.addDbItem(new CItem(3845, "Greater Assault", ItemSlot.WRIST, ItemType.ENCHANT, new CStats("AttackPower = 50")), true);
        l_result = this.addDbItem(new CItem(3231, "Expertise", ItemSlot.WRIST, ItemType.ENCHANT, new CStats("ExpertiseRating = 15")), true);
        l_result = this.addDbItem(new CItem(3829, "Assault", ItemSlot.HANDS, ItemType.ENCHANT, new CStats("AttackPower = 35")), true);
        l_result = this.addDbItem(new CItem(1594, "Greater Assault", ItemSlot.HANDS, ItemType.ENCHANT, new CStats("AttackPower = 26")), true);
        l_result = this.addDbItem(new CItem(1603, "Crusher", ItemSlot.HANDS, ItemType.ENCHANT, new CStats("AttackPower = 44")), true);
        l_result = this.addDbItem(new CItem(3231, "Expertise", ItemSlot.HANDS, ItemType.ENCHANT, new CStats("ExpertiseRating = 15")), true);
        l_result = this.addDbItem(new CItem(1103, "Exceptional Agility", ItemSlot.MAINHAND, ItemType.ENCHANT, new CStats("Agility = 26")), true);
        l_result = this.addDbItem(new CItem(2668, "Potency", ItemSlot.MAINHAND, ItemType.ENCHANT, new CStats("Strength = 20")), true);
        l_result = this.addDbItem(new CItem(1606, "Greater Potency", ItemSlot.MAINHAND, ItemType.ENCHANT, new CStats("AttackPower = 50")), true);
        l_result = this.addDbItem(new CItem(3833, "Superior Potency", ItemSlot.MAINHAND, ItemType.ENCHANT, new CStats("AttackPower = 65")), true);
        l_result = this.addDbItem(new CItem(3731, "Titanium Weapon Chain", ItemSlot.MAINHAND, ItemType.ENCHANT, new CStats("HitRating = 28")), true);


            //spell stuff

        l_result = this.addDbItem(new CItem(2935, "Precise Strikes", ItemSlot.HANDS, ItemType.ENCHANT, new CStats("HitRating = 15")), true);
        l_result = this.addDbItem(new CItem(3234, "Precision", ItemSlot.HANDS, ItemType.ENCHANT, new CStats("HitRating = 20")), true);
        l_result = this.addDbItem(new CItem(3788, "Accuracy", ItemSlot.MAINHAND, ItemType.ENCHANT, new CStats("CritRating = 25, HitRating = 25")), true);

        l_result = this.addDbItem(new CItem(2994, "Inscription of the Orb", ItemSlot.SHOULDERS, ItemType.ENCHANT, new CStats("CritRating = 13")), true);
 
        l_result = this.addDbItem(new CItem(2934, "Blasting", ItemSlot.HANDS, ItemType.ENCHANT, new CStats("CritRating = 10")), true);
        l_result = this.addDbItem(new CItem(3249, "Greater Blasting", ItemSlot.HANDS, ItemType.ENCHANT, new CStats("CritRating = 16")), true);


        l_result = this.addDbItem(new CItem(3004, "Arcanum of the Gladiator", ItemSlot.HEAD, ItemType.ENCHANT, new CStats("Stamina = 18, Resilience = 20")), true);
        l_result = this.addDbItem(new CItem(3842, "Arcanum of the Savage Gladiator", ItemSlot.HEAD, ItemType.ENCHANT, new CStats("Stamina = 30, Resilience = 25")), true);
        l_result = this.addDbItem(new CItem(3795, "Arcanum of Triumph", ItemSlot.HEAD, ItemType.ENCHANT, new CStats("AttackPower = 50, Resilience = 20")), true);

        l_result = this.addDbItem(new CItem(3793, "Inscription of Triumph", ItemSlot.SHOULDERS, ItemType.ENCHANT, new CStats("AttackPower = 40, Resilience = 15")), true);

        l_result = this.addDbItem(new CItem(2673, "Mongoose (Proc)", ItemSlot.MAINHAND, ItemType.ENCHANT, new CStats()), true);
        l_result = this.addDbItem(new CItem(3789, "Berserking (Proc)", ItemSlot.MAINHAND, ItemType.ENCHANT, new CStats()), true);
        l_result = this.addDbItem(new CItem(3225, "Executioner (Proc)", ItemSlot.MAINHAND, ItemType.ENCHANT, new CStats()), true);

        l_result = this.addDbItem(new CItem(3813, "Arcanum of Toxic Warding", ItemSlot.HEAD, ItemType.ENCHANT, new CStats("NatureResistance = 25, Stamina = 30")), true);
        l_result = this.addDbItem(new CItem(3815, "Arcanum of the Eclipsed Moon", ItemSlot.HEAD, ItemType.ENCHANT, new CStats("ArcaneResistance = 25, Stamina = 30")), true);
        l_result = this.addDbItem(new CItem(3816, "Arcanum of the Flame's Soul", ItemSlot.HEAD, ItemType.ENCHANT, new CStats("FireResistance = 25, Stamina = 30")), true);
        l_result = this.addDbItem(new CItem(3812, "Arcanum of the Frosty Soul", ItemSlot.HEAD, ItemType.ENCHANT, new CStats("FrostResistance = 25, Stamina = 30")), true);
        l_result = this.addDbItem(new CItem(3814, "Arcanum of the Fleeing Shadow", ItemSlot.HEAD, ItemType.ENCHANT, new CStats("ShadowResistance = 25, Stamina = 30")), true);

            //Sapphiron Enchants
        l_result = this.addDbItem(new CItem(2717, "Might of the Scourge", ItemSlot.SHOULDERS, ItemType.ENCHANT, new CStats("CritRating = 14, AttackPower = 26")), true);

            //Hodir Enchants
        l_result = this.addDbItem(new CItem(3808, "Greater Inscription of the Axe", ItemSlot.SHOULDERS, ItemType.ENCHANT, new CStats("AttackPower = 40, CritRating = 15")), true);
        l_result = this.addDbItem(new CItem(2986, "Lesser Inscription of the Axe", ItemSlot.SHOULDERS, ItemType.ENCHANT, new CStats("AttackPower = 30, CritRating = 10")), true);

            //Inscriber enchants
        l_result = this.addDbItem(new CItem(3835, "Master's Inscription of the Axe", ItemSlot.SHOULDERS, ItemType.ENCHANT, new CStats("CritRating = 15, AttackPower = 104")), true);

            //Leatherworking enchants
        l_result = this.addDbItem(new CItem(3756, "Fur Lining - Attack Power", ItemSlot.WRIST, ItemType.ENCHANT, new CStats("AttackPower = 114")), true);
        l_result = this.addDbItem(new CItem(3757, "Fur Lining - Stamina", ItemSlot.WRIST, ItemType.ENCHANT, new CStats("Stamina = 90")), true);
        l_result = this.addDbItem(new CItem(3327, "Jormungar Leg Reinforcements", ItemSlot.LEGS, ItemType.ENCHANT, new CStats("Stamina = 55, Agility = 22")), true);
        l_result = this.addDbItem(new CItem(3328, "Nerubian Leg Reinforcements", ItemSlot.LEGS, ItemType.ENCHANT, new CStats("AttackPower = 75, CritRating = 22")), true);

            // Engineering enchant
        l_result = this.addDbItem(new CItem(3604, "Hyperspeed Accelerators", ItemSlot.HANDS, ItemType.ENCHANT, new CStats("HasteRating = 56")), true);

        // Waist enchant
        l_result = this.addDbItem(new CItem(3722, "Eternal Belt Buckle", ItemSlot.WAIST, ItemType.ENCHANT, new CStats()), true);


        // Tailoring enchant
        // l_result = this.addDbItem(new CItem(3722, "Lightweave Embroidery", ItemSlot.BACK, ItemType.ENCHANT, new CStats("LightweaveEmbroideryProc = 1")), true);
    }

    public void addPoisons()
    {
        boolean l_result;

        l_result = this.addDbItem(new CItem(43233, "Deadly Poison", ItemSlot.MAINHAND, ItemType.POISON, new CStats()), true);
        l_result = this.addDbItem(new CItem(43235, "Wound Poison", ItemSlot.MAINHAND, ItemType.POISON, new CStats()), true);
        l_result = this.addDbItem(new CItem(43231, "Instant Poison", ItemSlot.MAINHAND, ItemType.POISON, new CStats()), true);
        l_result = this.addDbItem(new CItem(43237, "Anesthetic Poison", ItemSlot.MAINHAND, ItemType.POISON, new CStats()), true);
        l_result = this.addDbItem(this.m_nullItem, true);
    }

    public void handleMouseClick(JTable p_targetTable, MouseEvent p_evt)
    {
        if (p_evt.getClickCount() > 1)
        {
            int l_row = p_targetTable.rowAtPoint(new Point(p_evt.getX(), p_evt.getY()));
            int l_col = p_targetTable.convertColumnIndexToModel(p_targetTable.columnAtPoint(new Point(p_evt.getX(), p_evt.getY())));
            CItem l_itemId = (CItem) p_targetTable.getModel().getValueAt(l_row, l_col);
            if (l_itemId != null)
            {
                // Popup the dialog for viewing/deleting item
                boolean l_result = new CItemManager(CGlobal.g_jFrame, l_itemId).getValue();
                if (l_result == true)
                {
                    // User wants to delete the item
                    System.out.println("Removing item " + l_itemId.getName() + " from database");
                    m_itemMap.remove(l_itemId.getId());
                    this.saveDatabase();
                    this.setupGearData();
                    return;
                }
            }
        }
    }

    public void initItemDatabaseTables()
    {
        CDBTableModel l_armorTblModel = (CDBTableModel) m_armorTable.getModel();
        m_armorTable.setDefaultRenderer(CItem.class, new CDBRenderer(true));

        CDBTableModel l_weaponsTblModel = (CDBTableModel) m_weaponTable.getModel();
        m_weaponTable.setDefaultRenderer(CItem.class, new CDBRenderer(true));

        CDBTableModel l_gemsTblModel = (CDBTableModel) m_gemTable.getModel();
        m_gemTable.setDefaultRenderer(CItem.class, new CDBRenderer(true));

        l_armorTblModel.addColumn("Head");
        l_armorTblModel.addColumn("Neck");
        l_armorTblModel.addColumn("Shoulders");
        l_armorTblModel.addColumn("Back");
        l_armorTblModel.addColumn("Chest");
        l_armorTblModel.addColumn("Wrist");
        l_armorTblModel.addColumn("Hands");
        l_armorTblModel.addColumn("Waist");
        l_armorTblModel.addColumn("Legs");
        l_armorTblModel.addColumn("Boots");
        l_armorTblModel.addColumn("Ring");
        l_armorTblModel.addColumn("Trinket");

        l_weaponsTblModel.addColumn("Axe");
        l_weaponsTblModel.addColumn("MH Axe");
        l_weaponsTblModel.addColumn("OH Axe");
        l_weaponsTblModel.addColumn("Dagger");
        l_weaponsTblModel.addColumn("MH Dagger");
        l_weaponsTblModel.addColumn("OH Dagger");
        l_weaponsTblModel.addColumn("Fist");
        l_weaponsTblModel.addColumn("MH Fist");
        l_weaponsTblModel.addColumn("OH Fist");
        l_weaponsTblModel.addColumn("Mace");
        l_weaponsTblModel.addColumn("MH Mace");
        l_weaponsTblModel.addColumn("OH Mace");
        l_weaponsTblModel.addColumn("Sword");
        l_weaponsTblModel.addColumn("MH Sword");
        l_weaponsTblModel.addColumn("OH Sword");
        l_weaponsTblModel.addColumn("Bow");
        l_weaponsTblModel.addColumn("Crossbow");
        l_weaponsTblModel.addColumn("Gun");
        l_weaponsTblModel.addColumn("Thrown");

        l_gemsTblModel.addColumn("Meta");
        l_gemsTblModel.addColumn("Red");
        l_gemsTblModel.addColumn("Blue");
        l_gemsTblModel.addColumn("Green");
        l_gemsTblModel.addColumn("Orange");
        l_gemsTblModel.addColumn("Purple");
        l_gemsTblModel.addColumn("Yellow");
        l_gemsTblModel.addColumn("Prismatic");

        setupGearData();

        l_armorTblModel.setWidth(m_armorTable, 180);
        l_weaponsTblModel.setWidth(m_weaponTable, 180);
        l_gemsTblModel.setWidth(m_gemTable, 180);
    }

    public void setupGearData()
    {
        CDBTableModel l_armorTblModel = (CDBTableModel) m_armorTable.getModel();
        CDBTableModel l_weaponsTblModel = (CDBTableModel) m_weaponTable.getModel();
        CDBTableModel l_gemsTblModel = (CDBTableModel) m_gemTable.getModel();
        int l_column = 0;

        l_armorTblModel.cleanRows();

        // Add the data
        l_armorTblModel.addColumnData(CGlobal.g_database.getListBySlot(ItemSlot.HEAD),l_column++);
        l_armorTblModel.addColumnData(CGlobal.g_database.getListBySlot(ItemSlot.NECK),l_column++);
        l_armorTblModel.addColumnData(CGlobal.g_database.getListBySlot(ItemSlot.SHOULDERS),l_column++);
        l_armorTblModel.addColumnData(CGlobal.g_database.getListBySlot(ItemSlot.BACK),l_column++);
        l_armorTblModel.addColumnData(CGlobal.g_database.getListBySlot(ItemSlot.CHEST),l_column++);
        l_armorTblModel.addColumnData(CGlobal.g_database.getListBySlot(ItemSlot.WRIST),l_column++);
        l_armorTblModel.addColumnData(CGlobal.g_database.getListBySlot(ItemSlot.HANDS),l_column++);
        l_armorTblModel.addColumnData(CGlobal.g_database.getListBySlot(ItemSlot.WAIST),l_column++);
        l_armorTblModel.addColumnData(CGlobal.g_database.getListBySlot(ItemSlot.LEGS),l_column++);
        l_armorTblModel.addColumnData(CGlobal.g_database.getListBySlot(ItemSlot.FEET),l_column++);
        l_armorTblModel.addColumnData(CGlobal.g_database.getListBySlot(ItemSlot.FINGER),l_column++);
        l_armorTblModel.addColumnData(CGlobal.g_database.getListBySlot(ItemSlot.TRINKET),l_column++);
        l_armorTblModel.fireTableDataChanged();


        // Add the data
        l_weaponsTblModel.cleanRows();
        l_column = 0;
        l_weaponsTblModel.addColumnData(CGlobal.g_database.getListByTypeAndSlot(ItemType.AXE, ItemSlot.ONEHAND),l_column++);
        l_weaponsTblModel.addColumnData(CGlobal.g_database.getListByTypeAndSlot(ItemType.AXE, ItemSlot.MAINHAND),l_column++);
        l_weaponsTblModel.addColumnData(CGlobal.g_database.getListByTypeAndSlot(ItemType.AXE, ItemSlot.OFFHAND),l_column++);

                l_weaponsTblModel.addColumnData(CGlobal.g_database.getListByTypeAndSlot(ItemType.DAGGER, ItemSlot.ONEHAND),l_column++);
        l_weaponsTblModel.addColumnData(CGlobal.g_database.getListByTypeAndSlot(ItemType.DAGGER, ItemSlot.MAINHAND),l_column++);
        l_weaponsTblModel.addColumnData(CGlobal.g_database.getListByTypeAndSlot(ItemType.DAGGER, ItemSlot.OFFHAND),l_column++);

        l_weaponsTblModel.addColumnData(CGlobal.g_database.getListByTypeAndSlot(ItemType.FIST, ItemSlot.ONEHAND),l_column++);
        l_weaponsTblModel.addColumnData(CGlobal.g_database.getListByTypeAndSlot(ItemType.FIST, ItemSlot.MAINHAND),l_column++);
        l_weaponsTblModel.addColumnData(CGlobal.g_database.getListByTypeAndSlot(ItemType.FIST, ItemSlot.OFFHAND),l_column++);

        l_weaponsTblModel.addColumnData(CGlobal.g_database.getListByTypeAndSlot(ItemType.MACE, ItemSlot.ONEHAND),l_column++);
        l_weaponsTblModel.addColumnData(CGlobal.g_database.getListByTypeAndSlot(ItemType.MACE, ItemSlot.MAINHAND),l_column++);
        l_weaponsTblModel.addColumnData(CGlobal.g_database.getListByTypeAndSlot(ItemType.MACE, ItemSlot.OFFHAND),l_column++);

        l_weaponsTblModel.addColumnData(CGlobal.g_database.getListByTypeAndSlot(ItemType.SWORD, ItemSlot.ONEHAND),l_column++);
        l_weaponsTblModel.addColumnData(CGlobal.g_database.getListByTypeAndSlot(ItemType.SWORD, ItemSlot.MAINHAND),l_column++);
        l_weaponsTblModel.addColumnData(CGlobal.g_database.getListByTypeAndSlot(ItemType.SWORD, ItemSlot.OFFHAND),l_column++);

        l_weaponsTblModel.addColumnData(CGlobal.g_database.getListByType(ItemType.BOW),l_column++);
        l_weaponsTblModel.addColumnData(CGlobal.g_database.getListByType(ItemType.CROSSBOW),l_column++);
        l_weaponsTblModel.addColumnData(CGlobal.g_database.getListByType(ItemType.GUN),l_column++);
        l_weaponsTblModel.addColumnData(CGlobal.g_database.getListByType(ItemType.THROWN),l_column++);

        l_weaponsTblModel.fireTableDataChanged();

        // Add the data
        l_gemsTblModel.cleanRows();
        l_column = 0;
        l_gemsTblModel.addColumnData(CGlobal.g_database.getListForGems(CGemType.GemType.META),l_column++);
        l_gemsTblModel.addColumnData(CGlobal.g_database.getListForGems(CGemType.GemType.RED),l_column++);
        l_gemsTblModel.addColumnData(CGlobal.g_database.getListForGems(CGemType.GemType.BLUE),l_column++);
        l_gemsTblModel.addColumnData(CGlobal.g_database.getListForGems(CGemType.GemType.GREEN),l_column++);
        l_gemsTblModel.addColumnData(CGlobal.g_database.getListForGems(CGemType.GemType.ORANGE),l_column++);
        l_gemsTblModel.addColumnData(CGlobal.g_database.getListForGems(CGemType.GemType.PURPLE),l_column++);
        l_gemsTblModel.addColumnData(CGlobal.g_database.getListForGems(CGemType.GemType.YELLOW),l_column++);
        l_gemsTblModel.addColumnData(CGlobal.g_database.getListForGems(CGemType.GemType.PRISMATIC),l_column++);

        l_gemsTblModel.fireTableDataChanged();
    }
}
